/*
 * ==================================================================
 * Pardal - Framework for Classification Hierarchical and Multilabel.
 * ==================================================================
 * 
 * Copyright (C) 2013-2014 
 *  Valdigleis da Silva Costa
 *  Araken Medeiros Santos
 *  Daniel Sabino Amorim de Araujo
 *
 *  Departamento de Ciências Exatas, Tecnologicas e Humanas (DCETH) 
 *  Grupo de Inteligência Computacionais de Angicos (GICA)
 *  Campus Angicos (CA)
 *  Universidade Federal Rural do Semi-árido (UFERSA)
 *
 *  Project Info: (Site em desenvolvimento)
 * 
 * Framework Pardal is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * Framework Pardal is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 * 
 * ==================================================================
 * Pardal - Framework para Classificação Hierárquica e Multirrótulo.
 * ==================================================================
 * 
 * Copyright (C) 2013-2014 
 *  Valdigleis da Silva Costa
 *  Araken Medeiros Santos
 *  Daniel Sabino Amorim de Araujo
 *
 *  Departamento de Ciências Exatas, Tecnologicas e Humanas (DCETH) 
 *  Grupo de Inteligência Computacionais de Angicos (GICA)
 *  Campus Angicos (CA)
 *  Universidade Federal Rural do Semi-árido (UFERSA)
 *
 * Informações sobre o projeto: (Site em Desenvolvimento)
 * 
 * O Framework Pardal é um software livre; você pode redistribui-lo e/ou
 * modifica-lo dentro dos termos da Licença Pública Geral GNU como 
 * publicada pela Fundação do Software Livre (FSF); na versão 2 da 
 * Licença, ou (na sua opnião) qualquer versão.
 * 
 * O Framework Pardal é distribuido na esperança que possa ser util, 
 * mas SEM NENHUMA GARANTIA; sem uma garantia implicita de ADEQUAÇÂO
 * a qualquer MERCADO ou APLICAÇÃO EM PARTICULAR. Veja a
 * Licença Pública Geral GNU para maiores detalhes.
 * 
 * Você deve ter recebido uma cópia da Licença Pública Geral GNU
 * junto com este programa, se não, escreva para a Fundação do Software
 * Livre(FSF) Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

package pardal.gica.gui;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.text.ParseException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import pardal.gica.code.util.FilterFiles;
import pardal.gica.gui.config.ensembles.ConfigBagging;
import weka.core.Instances;

/**
 *
 * @author Valdigleis
 */
public class HierarquicSelection extends JFrame {
    
    private int                 option;            //Guarda a opção de classificação usada 1-HMLP, 2-HMC, 3-HBR.
    protected Instances         instances;         //Objeto que guarda as instancias do arquivo base arff.
    
    private JFileChooser        selectoFile;       //seletor de arquivos a ser inserido no botão abrir arquivo.
    private FilterFiles         filterSelector;    //filtro para ser aplicado no seletor do botão abrir arquivo.
    private JButton             open_File;         //botão abrir que selecionarar os arquivos arff.
    private JTextField          path_File;         //campo de texto para o path do arquivo.
    private File                file;              //objeto que faz a leitura do arquivo base.
    private JButton             close_File;        //botão para apagar o file.
    
    private JLabel              labelInfo1;        //label que marca o local dos classificadores simples.
    private JButton             knn;               //botão para Configuração do KNN.
    private JButton             naive;             //botão para Configuração do Naive.
    private JButton             neural;            //botão para Configuração do Redes Neurais.
    private JButton             tree;              //botão para Configuração de Arvore de Decisão.
    private JLabel              labelInfo2;        //label que marca o local dos comitês classificadores.
    private JButton             bagging;           //botão para Configuração do comitê Bagging.
    private JButton             boosting;          //botão para Configuração do comitê Boosting.
    private JButton             stacking;          //botão para Configuração do comitê Stacking.
    
    
    private JButton             teste;             //botão para Configuração do comitê Stacking.

    /**
     * Construtor da janela de seleção de classificador base para o método de classificação.
     * @param option - opção selecionada 1-HMLP, 2-HMC ou 3-HBR.
     */
    public HierarquicSelection(int option) {
        super();
        this.option = option;
        initComponents();
    }
    
    /**
     * Método que inicializa os componentes básicos das jenelas de todos os módulos.
     */
    private void initComponents(){
        
        //incializa os componentes básicos da interface.
        this.selectoFile = new JFileChooser();
        this.filterSelector = new FilterFiles();
        this.open_File = new JButton("Abrir");
        this.path_File = new JTextField();
        this.close_File = new JButton("Remover");
        this.file = null;
        
        //iniciar as configurações da janela
        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setResizable(false);
        getContentPane().setLayout(null);
        setSize(335, 400);
        setTitle(getTitleLocal());
        setLocationRelativeTo(null);
        
        //seta os paramentros dos componentes básicos.
        this.selectoFile.setFileFilter(filterSelector);
        this.open_File.setToolTipText("Abrir arquivo base no formato arff");
        this.open_File.setBounds(10, 25, 70, 25);
        this.open_File.addActionListener(new java.awt.event.ActionListener() {
            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getFile(evt);
            }
        });
        this.path_File.setEditable(false);
        this.path_File.setText("Arquivo base");
        this.path_File.setToolTipText("Caminho para o arquivo base no formato arff");
        this.path_File.setBounds(80, 25, 150, 25);
        this.close_File.setToolTipText("Remove o arquivo base");
        this.close_File.setBounds(228, 25, 90, 25);
        this.close_File.addActionListener(new java.awt.event.ActionListener() {
            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                removeFile(evt);
            }
        });
        
        this.labelInfo1 = new JLabel("Classificadores Individuais");
        this.labelInfo1.setBounds(90, 75, 250, 25);
        
        this.knn = new JButton("K-Nearest Neighbor");
        this.knn.setToolTipText("Seta configuração do algoiritmo K vizinhos mais próximos");
        this.knn.setBounds(40, 100, 250, 25);
        this.knn.addActionListener(new java.awt.event.ActionListener() {
            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                try {
                    configKNN();
                } catch (ParseException ex) {
                    Logger.getLogger(HierarquicSelection.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
        
        this.naive = new JButton("Naive Bayse");
        this.naive.setToolTipText("Seta configuração do algoiritmo Naive Bayse");
        this.naive.setBounds(40, 125, 250, 25);
        this.naive.addActionListener(new java.awt.event.ActionListener() {
            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                try {
                    configNaive();
                } catch (ParseException ex) {
                    Logger.getLogger(HierarquicSelection.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
        
        this.neural = new JButton("RNA - Preceptron");
        this.neural.setToolTipText("Seta configuração do algoiritmo Perceptron");
        this.neural.setBounds(40, 150, 250, 25);
        this.neural.addActionListener(new java.awt.event.ActionListener() {
            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                try {
                    configRNA();
                } catch (ParseException ex) {
                    Logger.getLogger(HierarquicSelection.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
        
        this.tree = new JButton("Decision Tree");
        this.tree.setToolTipText("Seta configuração do algoiritmo Árvore de Decisão (J48)");
        this.tree.setBounds(40, 175, 250, 25);
        this.tree.addActionListener(new java.awt.event.ActionListener() {
            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                try {
                    configJ48();
                } catch (ParseException ex) {
                    Logger.getLogger(HierarquicSelection.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
        
        this.labelInfo2 = new JLabel("Comitês de Classificadores");
        this.labelInfo2.setBounds(90, 215, 250, 25);
        
        this.bagging = new JButton("Bagging");
        this.bagging.setToolTipText("Seta configuração do Comitês Bagging");
        this.bagging.setBounds(40, 240, 250, 25);
        this.bagging.addActionListener(new java.awt.event.ActionListener() {
            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                try {
                    ConfigBagging();
                } catch (ParseException ex) {
                    Logger.getLogger(HierarquicSelection.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
        
        this.boosting = new JButton("Boosting");
        this.boosting.setToolTipText("Seta configuração do Comitês Boosting");
        this.boosting.setBounds(40, 265, 250, 25);
        
        this.stacking = new JButton("Stacking");
        this.stacking.setToolTipText("Seta configuração do Comitês Stacking");
        this.stacking.setBounds(40, 290, 250, 25);
        
        JLabel image = new JLabel();
        image.setIcon(new javax.swing.ImageIcon(getClass().getResource("/pardal/resource/fundo.png")));
        image.setBounds(0, 0, 600, 400);
        
        //seta os componentes básicos na janela.
        this.add(this.open_File);
        this.add(this.path_File);
        this.add(this.close_File);
        this.add(this.labelInfo1);
        this.add(this.knn);
        this.add(this.naive);
        this.add(this.neural);
        this.add(this.tree);
        this.add(this.labelInfo2);
        this.add(this.bagging);
        this.add(this.boosting);
        this.add(this.stacking);
        
        this.teste = new JButton("Rodar Classificação");
        this.teste.setBounds(40, 335, 250, 25);
        this.teste.addActionListener(new java.awt.event.ActionListener() {
            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                Run();
            }
        });
        
        this.add(this.teste);
        this.add(image);
        setVisible(true);
    }
    
    /**
     * Método que realiza a captura do arquivo base para o software.
     * @param evt Evento de clique do botão "Abrir Arquivo".
     */
    private void getFile(java.awt.event.ActionEvent evt){
        int returnVal = this.selectoFile.showOpenDialog(this);
        if (returnVal == this.selectoFile.APPROVE_OPTION) {
            try {
                //seta o path do arquivo base na interface gráfica.
                this.file = this.selectoFile.getSelectedFile();
                this.path_File.setText(file.getName());
                
                //inicializa o objeto responsavel pela instãncias durante a execução do software;
                FileReader reader = new FileReader(file.getCanonicalPath().trim());
                this.instances = new Instances(reader);
                
            } catch (IOException ex) {
                JOptionPane.showMessageDialog(this, "Erro com o arquivo");
            }
        }
    }
    
    
    /**
     * Método que remove o arquivo base e limpa o cache do software.
     * @param evt Evento de clique do botão "Remove".
     */
    private void removeFile(java.awt.event.ActionEvent evt){
        if(path_File.getText().trim().equals("Arquivo base")){
            JOptionPane.showMessageDialog(this, "Nenhum arquivo base selecionado");
        }else{
            this.path_File.setText("Arquivo base");
            this.file.delete();
        }
    }
    
    
    private void configKNN() throws ParseException{
        if(testFile()){
            
        }
    }
    
    private void configNaive() throws ParseException{
        if(testFile()){
            
        }
    }
    
    private void configRNA() throws ParseException{
        if(testFile()){
        }
    }
    
    private void configJ48() throws ParseException{
        if(testFile()){
            
        }
    }
    
    private void ConfigBagging() throws ParseException{
        if(testFile()){
            new ConfigBagging(this, this.option, instances);
        }
    }
    
    private boolean testFile(){
        if(path_File.getText().trim().equals("Arquivo base")){
            JOptionPane.showMessageDialog(this, "Nenhum arquivo base selecionado");
            return false;
        }else{
            return true;
        }
    }
    
    private void Run() {
        
    }
    
    private String getTitleLocal(){
        if(this.option == 1){
            return ("Pardal - HMLP");
        }
        if(this.option == 2){
            return ("Pardal - HMC");
        }
        if(this.option == 3){
            return ("Pardal - HBR");
        }
        return null;
    }
    
}
